/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { CoreTask } from '../../../external/task/core-task.js';
import { HvigorLogger } from '../../../log/hvigor-log.js';
import { TaskContainer } from '../interface/task-container-interface.js';
import { TaskCreation } from './lazy-task-container.js';
import { projectTaskDag, TaskDirectedAcyclicGraph } from './task-directed-acyclic-graph.js';

/**
 * module的Task容器管理的默认实现
 *
 * @since 2022/4/24
 */
export class DefaultTaskContainer implements TaskContainer {
  private readonly _moduleName: string;
  private _tasks: Map<string, CoreTask>;
  private _taskGraph: TaskDirectedAcyclicGraph;
  private _log = HvigorLogger.getLogger(DefaultTaskContainer.name);

  constructor(moduleName: string, taskGraph: TaskDirectedAcyclicGraph) {
    this._moduleName = moduleName;
    this._tasks = new Map<string, CoreTask>();
    this._taskGraph = taskGraph;
  }

  registryTask(creation: TaskCreation): void {
    throw new Error('Method not implemented.');
  }

  getTaskPaths(): string[] {
    return [...this._tasks.keys()];
  }

  registerTask(action: TaskCreation): void {
    throw new Error('Method not implemented.');
  }

  getTaskDepends(taskPath: string): string[] {
    const task: CoreTask | undefined = this.findTask(taskPath);
    if (!task) {
      throw new Error(`Task not found ${taskPath}.`);
    }
    return task.getDependsOn();
  }

  addTask(task: CoreTask): void {
    const taskName = task.getName();
    if (this._tasks.has(taskName)) {
      this._log.printErrorExit('DUPLICATE_TASK', [taskName, task.getPath()]);
    }
    this._tasks.set(taskName, task);
    this._taskGraph.addNode(task.getPath());
    projectTaskDag.addNode(task.getPath());
  }

  deleteTask(taskName: string): boolean {
    if (this.hasTask(taskName)) {
      const taskPath = this._tasks.get(taskName)!.getPath();
      this._taskGraph.removeNode(taskPath);
      projectTaskDag.removeNode(taskPath);
      this._tasks.delete(taskName);
      return true;
    }
    return false;
  }

  findTask(taskName: string): CoreTask | undefined {
    return this._tasks.get(taskName);
  }

  getAllTasks(): CoreTask[] {
    return [...this._tasks.values()];
  }

  hasTask(taskName: string): boolean {
    return this._tasks.has(taskName);
  }

  clearTasks() {
    this._tasks.clear();
    this._taskGraph.clear();
  }
}
